"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 故障&可靠性测试
Case Name   : 修改pg_hba文件中指定主机的权限，备份再恢复
Create At   : 2020/12/1
@zou_jialiang0505328126
Description :
    1.在pg_hba文件中删除备节点2并重启数据
    2.备节点2重建
    3.备份数据
    4.恢复pg_hba文件中备节点2并重启数据
    5.备节点2重建
    6.恢复数据库
    7.备节点2重建
    8.恢复pg_hba文件中备节点2并重启数据
    9.重建备节点2
    10.备份数据库
    11.在pg_hba文件中删除备节点2并重启数据
    12.备节点2重建
    13.恢复数据库
    14.重建备节点2
Expect      :
    1.删除成功
    2.重建失败
    3.备份成功
    4.恢复pg_hba文件中备节点2信息成功
    5.重建成功
    6.恢复数据库成功
    7.重建失败
    8.恢复pg_hba文件中备节点2信息成功
    9.重建成功
    10.备份成功
    11.删除pg_hba文件中备节点2信息成功
    12.重建失败
    13.恢复数据库成功
    14.备节点2重建成功
History     :
    Modified by @wan005 2021/1/7: 适配pg_hba.conf文件中存在重复内容的场景
    Modified by @wan005 22021/10/14:适配2.1.0版本，修改pg_hba后需重启数据库
    Modified by @wan005 2022/3/14:适配3.0.0版本，pg_hba文件内容变更
"""

import os
import unittest
import sys
from yat.test import macro
from yat.test import Node

sys.path.append(sys.path[0] + "/../")
from testcase.utils.CommonSH import *
from testcase.utils.Common import Common
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class Basebackup(unittest.TestCase):
    commonshpri = CommonSH('PrimaryDbUser')
    commonshsta = CommonSH('Standby1DbUser')
    commonshsta2 = CommonSH('Standby2DbUser')
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info('------------Opengauss_Reliability_Tools_Backup_Case039.py 开始执行------------')
        self.dbPrimaryDbUser = Node(node='PrimaryDbUser')
        self.dbStandby1DbUser = Node(node='Standby1DbUser')
        self.dbStandby2DbUser = Node(node='Standby2DbUser')
        self.dbStandby1Root = Node(node='Standby1Root')
        self.dbPrimaryRootNode = Node(node='PrimaryRoot')
        self.Constant = Constant()
        self.common = Common('PrimaryRoot')
        self.backup_file = os.path.join(macro.DB_BACKUP_PATH, 'backup_dir')
        self.primary_hostname = self.dbPrimaryDbUser.sh('hostname').result()

        self.log.info('-------------------创建备份路径-----------------------------------')
        shell_cmd = f'rm -rf {self.backup_file}; mkdir {self.backup_file};'
        self.log.info(shell_cmd)
        result = self.dbPrimaryDbUser.sh(shell_cmd).result()
        self.log.info(result)

    def test_backup(self):
        text = '----step1: 在pg_hba文件中删除备节点2,并重启数据 expect:删除成功----'
        self.log.info(text)
        shell_cmd = f"cp " \
            f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')} " \
            f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conftestbak')}"
        self.log.info(shell_cmd)
        result = self.dbPrimaryDbUser.sh(shell_cmd).result()
        self.log.info(result)
        shell_cmd = f"grep -n '{self.dbStandby2DbUser.ssh_host}'  " \
            f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')} " \
            f"| cut -d \":\" -f 1"
        self.log.info(shell_cmd)
        result = self.dbPrimaryDbUser.sh(shell_cmd).result()
        self.log.info(result)
        lines = result.strip().splitlines()
        repeat = 0
        j = 0
        for i in lines:
            if repeat > 0:
                line = str(int(i)-j)
            else:
                line = i
            shell_cmd = f"sed -i '{line}d' " \
                f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')}"
            self.log.info(shell_cmd)
            result = self.dbPrimaryDbUser.sh(shell_cmd).result()
            self.log.info(result)
            repeat = repeat+1
            j += 1
        result = self.dbPrimaryDbUser.sh(
            f"cat {os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')}"
        ).result()
        self.log.info(result)
        result = self.commonshpri.stopDbCluster()
        self.assertTrue(result, '执行失败:' + text)
        result = self.commonshpri.startDbCluster()
        self.assertFalse(result, '执行失败:' + text)

        text = '----step2: 备节点2重建 expect:失败----'
        self.log.info(text)
        result = self.commonshsta2.buildStandby()
        self.log.info(result)
        self.assertNotIn(self.Constant.BUILD_SUCCESS_MSG, result,
                         '执行失败:' + text)

        text = '----step3: 备份数据 expect:成功----'
        self.log.info(text)
        result = self.commonshsta.execu_gs_backup(
            'backup', self.primary_hostname, self.backup_file, "--all", )
        self.assertIn(self.Constant.BACKUP_BACKUP_SUCCESS_MSG, result,
                      '执行失败:' + text)
        cmd = f'ls -l {self.backup_file} |grep "^-"|wc -l'
        self.log.info(cmd)
        result = self.dbPrimaryRootNode.sh(cmd).result()
        self.log.info(result)
        self.assertLess(0, int(result))

        text = '----step4: 恢复pg_hba文件中备节点2 expect:成功----'
        self.log.info(text)
        shell_cmd = f"rm -rf " \
            f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')};cp " \
            f"{os.path.join( macro.DB_INSTANCE_PATH, 'pg_hba.conftestbak')}" \
            f" {os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')} "
        self.log.info(shell_cmd)
        result = self.dbPrimaryDbUser.sh(shell_cmd).result()
        self.log.info(result)
        result = self.commonshpri.stopDbCluster()
        self.assertTrue(result, '执行失败:' + text)
        result = self.commonshpri.startDbCluster()
        self.assertTrue(result, '执行失败:' + text)

        text = '----step5: 备节点2重建  expect:成功----'
        self.log.info(text)
        result = self.commonshsta2.buildStandby()
        self.log.info(result)
        self.assertIn(self.Constant.BUILD_SUCCESS_MSG, result, '执行失败:' + text)

        text = '----step6:恢复数据库  expect:成功----'
        self.log.info(text)
        result = self.commonshsta.execu_gs_backup(
            'restore', self.primary_hostname, self.backup_file, "--all")
        self.assertIn(self.Constant.BACKUP_RESTORE_SUCCESS_MSG, result,
                      '执行失败:' + text)
        result = self.commonshpri.stopDbCluster()
        self.assertTrue(result, '执行失败:' + text)
        result = self.commonshpri.startDbCluster()
        self.assertFalse(result, '执行失败:' + text)

        text = '----step7: 备节点2重建 expect:失败----'
        self.log.info(text)
        result = self.commonshsta2.buildStandby()
        self.log.info(result)
        self.assertNotIn(self.Constant.BUILD_SUCCESS_MSG, result,
                         '执行失败:' + text)

        text = '----step8: 恢复pg_hba文件中备节点2 expect:成功----'
        self.log.info(text)
        shell_cmd = f"ls -al " \
            f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')};" \
            f"rm -rf " \
            f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')}; " \
            f"cp {os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conftestbak')} " \
            f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')} "
        self.log.info(shell_cmd)
        result = self.dbPrimaryDbUser.sh(shell_cmd).result()
        self.log.info(result)
        result = self.commonshpri.stopDbCluster()
        self.assertTrue(result, '执行失败:' + text)
        result = self.commonshpri.startDbCluster()
        self.assertTrue(result, '执行失败:' + text)

        text = '----step9: 备节点2重建  expect:成功----'
        self.log.info(text)
        result = self.commonshsta2.buildStandby()
        self.log.info(result)
        self.assertIn(self.Constant.BUILD_SUCCESS_MSG, result, '执行失败:' + text)

        text = '----step10: 备份数据 expect:成功----'
        self.log.info(text)
        result = self.commonshsta.execu_gs_backup(
            'backup', self.primary_hostname, self.backup_file, "--all", )
        self.assertIn(self.Constant.BACKUP_BACKUP_SUCCESS_MSG, result,
                      '执行失败:' + text)
        cmd = f'ls -l {self.backup_file} |grep "^-"|wc -l'
        self.log.info(cmd)
        result = self.dbPrimaryRootNode.sh(cmd).result()
        self.log.info(result)
        self.assertLess(0, int(result), '执行失败:' + text)

        text = '----step11:在pg_hba文件中删除备节点2 expect:成功----'
        self.log.info(text)
        shell_cmd = f"grep -n '{self.dbStandby2DbUser.ssh_host}' " \
            f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')}| " \
            f"cut -d \":\" -f 1"
        self.log.info(shell_cmd)
        result = self.dbPrimaryDbUser.sh(shell_cmd).result()
        self.log.info(result)
        lines = result.strip().splitlines()
        repeat = 0
        j = 0
        for i in lines:
            if repeat > 0:
                line = str(int(i) - j)
            else:
                line = i
            shell_cmd = f"sed -i '{line}d' " \
                f"{os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')}"
            self.log.info(shell_cmd)
            result = self.dbPrimaryDbUser.sh(shell_cmd).result()
            self.log.info(result)
            repeat = repeat + 1
            j += 1
        result = self.dbPrimaryDbUser.sh(
            f"cat {os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')}"
            f"").result()
        self.log.info(result)
        result = self.commonshpri.stopDbCluster()
        self.assertTrue(result, '执行失败:' + text)
        result = self.commonshpri.startDbCluster()
        self.assertFalse(result, '执行失败:' + text)

        text = '----step12:备节点2重建 expect:失败----'
        self.log.info(text)
        result = self.commonshsta2.buildStandby()
        self.log.info(result)
        self.assertNotIn(self.Constant.BUILD_SUCCESS_MSG, result,
                         '执行失败:' + text)

        text = '----step13:恢复数据库 expect:成功----'
        self.log.info(text)
        result = self.commonshsta.execu_gs_backup(
            'restore', self.primary_hostname, self.backup_file, "--all")
        self.assertIn(self.Constant.BACKUP_RESTORE_SUCCESS_MSG, result,
                      '执行失败:' + text)
        result = self.commonshpri.stopDbCluster()
        self.assertTrue(result, '执行失败:' + text)
        result = self.commonshpri.startDbCluster()
        self.assertTrue(result, '执行失败:' + text)

        text = '----step14:备节点2重建 expect:成功----'
        self.log.info(text)
        result = self.commonshsta2.buildStandby()
        self.log.info(result)
        self.assertIn(self.Constant.BUILD_SUCCESS_MSG, result, '执行失败:' + text)

    def tearDown(self):
        self.log.info('-------------------------环境清理------------------------')
        self.log.info('--------------------------删除备份文件------------------')
        shell_cmd = f'rm -rf {self.backup_file}'
        self.log.info(shell_cmd)
        result = self.dbPrimaryDbUser.sh(shell_cmd).result()
        self.log.info(result)
        result = self.dbStandby1DbUser.sh(shell_cmd).result()
        self.log.info(result)
        result = self.dbStandby2DbUser.sh(shell_cmd).result()
        self.log.info(result)

        self.log.info("-----------------------------恢复postgres.conf：成功---------------------------------")
        shell_cmd = f'''rm -rf {os.path.join(macro.DB_INSTANCE_PATH, 'pg_hba.conf')};cp {os.path.join(
            macro.DB_INSTANCE_PATH, 'pg_hba.conftestbak')} {os.path.join(macro.DB_INSTANCE_PATH,
                                                                         'pg_hba.conf')};rm -rf  {os.path.join(
            macro.DB_INSTANCE_PATH, 'pg_hba.conftestbak')}'''
        self.log.info(shell_cmd)
        result = self.dbPrimaryDbUser.sh(shell_cmd).result()
        self.log.info(result)

        self.log.info('----------Opengauss_Reliability_Tools_Backup_Case039.py 执行结束-----------------------')
